package infoserver;

import Protocol.*;
import java.net.*;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;


/**
 * Deze klasse wordt gestart zodra een client verbinding maakt met de serversocket
 * Hier worden de aanvragen van de client afgehandeld
 * @author Michael Stevens
 * @since 03-05-2012
 */
public class InfoServerThread implements Runnable{
    private Infoserver is;
    private Socket clientSocket;
    private ComProtocol cp; 
    private int id = 0;
    
    public InfoServerThread(Socket socket, Infoserver is){        
        this.clientSocket = socket;
        this.is = is;  
       
    }
    
    /**
    * Verwerk een inlog request
    * Geef ok mee bij success en error bij fout
    * @author Michael Stevens
    * @since 04-05-2011
    */
    public void processInloggen(ClientObject co, boolean isMaster){
        id = is.getLogin().excecuteLogin(co.getUsername(), co.getPassword(), isMaster);
            if(id >=1){
                ReturnObject ro = new ReturnObject();
                ro.setMessage(ro.getOk());
                cp.send(ro);
            } else {
                ReturnObject ro = new ReturnObject();
                ro.setMessage(ro.getError());
                cp.send(ro);
            }
    }   
    
    /**    
    * Zet id op 0 en stuur terug dat het gelukt is
    * @author Michael Stevens
    * @since 04-05-2011
    */
    public void processUitloggen(){
        id = 0;
        ReturnObject ro = new ReturnObject();
        ro.setMessage(ro.getOk());
        cp.send(ro);
    }    
    
    
    /**
    * Verwerkt een SelectQuery en verstuurt het resultaat 
    * @author Michael Stevens
    * @since 03-05-2011
    */
    private void processSelectQuery(String query){
        ResultSet rs = is.getSql().excecuteSelectQuery(query);
        ReturnObject ro = new ReturnObject();
        try{
            if(rs.next()){
                ro.setMessage(ro.getOk());
                rs.previous();
            }else{                
                ro.setMessage(ro.getError());
            }            
            cp.send(preTransport(rs,ro));
        }catch(Exception e){
            System.out.println(e.getMessage());            
        }
    } 
    
    /**
    * Verwerkt een UpdateQuery en verstuurt het resultaat 
    * @author Michael Stevens
    * @since 03-05-2011
    */
    public void processUpdateQuery(String query){
       int success = is.getSql().excecuteUpdateQuery(query);
       ReturnObject ro = new ReturnObject();
       if(success == 0){
           ro.setMessage(ro.getError());
       }else{
           ro.setMessage(ro.getOk());
       }
       cp.send(ro);
    }
    
    /**
    * Prepareert een resultaat voor transport door het om te zetten naar een ReturnObject 
    * @author Michael Stevens
    * @since 03-05-2011
    */
     public ReturnObject preTransport(ResultSet rs, ReturnObject ro){ 
        try{
            ResultSetMetaData meta = rs.getMetaData(); // haal meta data op
            
            ArrayList<String> kolom = new ArrayList<String>(); // maak eenmalig een array aan voor de kolom namen
            boolean first = true; // aanduiding voor de eerste iteratie

            while(rs.next()){ // cycle door de rijen van het resultaat
                ArrayList<String> rij = new ArrayList<String>(); // maak voor elke rij een array aan
                for(int i = 0; i < meta.getColumnCount();i++){ // voor het aantal kolommen
                    if(first){// dit wordt alleen in de eerste iteratie uitgevoerd
                        kolom.add(meta.getColumnName(i+1));// schrijf de kolom naam weg naar het array
                    }
                    rij.add(rs.getString(meta.getColumnName(i+1)));// schrijf de kolom data weg naar het array
                }

                if(first){// dit wordt alleen in de eerste iteratie uitgevoerd
                    ro.setColumns(kolom); //plaats het array in het ReturnObject
                }
                first = false; // geef aan dat de eerste iteratie voorbij is
                ro.addRows(rij);// plaats het array in de array van het ReturnObject
            }            
          }catch(SQLException ex){
            System.out.println(ex.getMessage() + "pretrans EX");
          }
        
        return ro;
    } 
    
    
    /**
    * Start het protocol en kijkt om welke actie de client vraagt
    * @author Michael Stevens
    * @since 03-05-2011
    */
    public void run(){
        cp = new ComProtocol(clientSocket);
        
        ClientObject co = (ClientObject) cp.recieve();
        
        if(co.getAction().equals(cp.getInloggen())){
            processInloggen(co, false);
        }else if(co.getAction().equals(cp.getInloggenMaster())){            
            processInloggen(co, true);
        }else{
            id = is.getLogin().excecuteLogin(co.getUsername(), co.getPassword(), false);
        }
        
        if(id >= 1){// kijk of gebruiker is ingelogd
            if(co.getAction().equals(cp.getSelectQuery())){
                processSelectQuery(co.getCommand());
            }else if(co.getAction().equals(cp.getUpdateQuery())){
                processUpdateQuery(co.getCommand());
            }else if(co.getAction().equals(cp.getUitloggen())){
                processUitloggen();
            }       
        }
        cp.close();
     }
        
}   
    


